﻿using System;  
using System.Collections.Generic;  

public class EventArgs  
{  
	
}  

public class EventManager  
{  
	static EventManager instance;  
	public static EventManager GetInstance  
	{  
		get  
		{  
			if (instance == null)  
			{  
				instance = new EventManager();  
			}  
			
			return instance;  
		}  
	}  
	
	public delegate void EventDelegate<T>(T e) where T : EventArgs;  
	
	readonly Dictionary<Type, Delegate> _delegates = new Dictionary<Type, Delegate>();  
	
	public void AddListener<T>(EventDelegate<T> listener) where T : EventArgs  
	{  
		Delegate d;  
		if (_delegates.TryGetValue(typeof(T), out d))  
		{  
			_delegates[typeof(T)] = Delegate.Combine(d, listener);  
		}  
		else  
		{  
			_delegates[typeof(T)] = listener;  
		}  
	}  
	
	public void RemoveListener<T>(EventDelegate<T> listener) where T : EventArgs  
	{  
		Delegate d;  
		if (_delegates.TryGetValue(typeof(T), out d))  
		{  
			Delegate currentDel = Delegate.Remove(d, listener);  
			
			if (currentDel == null)  
			{  
				_delegates.Remove(typeof(T));  
			}  
			else  
			{  
				_delegates[typeof(T)] = currentDel;  
			}  
		}  
	}  
	
	public void Raise<T>(T e) where T : EventArgs  
	{  
		if (e == null)  
		{  
			throw new ArgumentNullException("e");  
		}  
		
		Delegate d;  
		if (_delegates.TryGetValue(typeof(T), out d))  
		{  
			EventDelegate<T> callback = d as EventDelegate<T>;  
			if (callback != null)  
			{  
				callback(e);  
			}  
		}  
	}  
} 